<script setup lang="ts">
import { reactive, ref, watchEffect } from "vue";
import type { FormInstance } from "vant";
import FormComponent from "./components/Component/index.vue";
import { computed } from "@vue/reactivity";

interface Props {
  formTitle?: string;
  list?: API.Form.ControlItem[];
  mode?: API.Form.Mode;
}

const props = withDefaults(defineProps<Props>(), {
  formRef: undefined,
  mode: "edit",
  list: () => [],
});

const formValue: any = reactive({});
const formRef = ref<FormInstance>();

const onSubmit = () => {
  return new Promise((resolve) => {
    formRef.value?.validate().then(() => {
      resolve(formValue);
    });
  });
};

const data = computed(() => {
  const dataList = props.list?.map((val) => ({
    ...val,
    controlAttr:
      typeof val.controlAttr === "string"
        ? JSON.parse(val.controlAttr)
        : val.controlAttr ?? {},
  }));
  return dataList;
});

// 暴露给ref的方法
defineExpose({
  submit: onSubmit,
  validate: formRef.value?.submit,
  getValues: () => formValue,
});

watchEffect(() => {
  // 初始化默认值
  for (const val of props.list) {
    formValue[val.controlId] = val?.controlAttr?.defaultValue;
  }
});
</script>

<template>
  <div class="form-title">{{ formTitle }}</div>
  <van-form ref="formRef" class="smart-form" @submit="onSubmit">
    <van-cell-group inset class="group">
      <FormComponent
        v-for="item in data"
        :key="item.controlId"
        v-model="formValue[item.controlId]"
        :control-item="item"
        :mode="mode"
      />
    </van-cell-group>
  </van-form>
</template>

<style scoped lang="scss">
.form-title {
  font-size: 32px;
  line-height: 100px;
  text-align: center;
  color: #333;
}
.smart-form {
  ::v-deep {
    .van-field__label {
      display: flex;
      flex-direction: row-reverse;
      justify-content: flex-end;
      width: 100%;
    }
    .van-field__label--required:before {
      margin-left: 6px;
      font-size: 34px;
      color: #f53f3f;
      position: relative;
      top: 3px;
    }
    .van-cell {
      display: block;
      padding-bottom: 0;
    }
    .van-field__body {
      min-height: 68px;
    }
  }
}
.group {
  padding-bottom: 24px;
}
</style>
